<?php
namespace App\Controllers\Sms;

use App\Controllers\BaseController;
use App\Library\App;
use App\Library\Helper;
use App\Library\SmsGateway\Adapter as SmsAdapter;
use App\Models\SmsMtLoger;
use App\Models\SmsMtTempQueue;
use App\Models\SmsSaleforceMtTempQueue;

class IndexController extends BaseController {

    public function initialize() {
        parent::initialize();
    }

    public function indexAction() {
        App::Logger()->debug('-----');
    }

    //-------------------------------------------------------------------------
    // 下发验证码短信
    //-------------------------------------------------------------------------
    public function mtAction() {
        $this->send('captcha');
    }

    //-------------------------------------------------------------------------
    // 下发通知短信
    //-------------------------------------------------------------------------

    private function send($act) {
        $config          = $this->getDI()->get('globalConfig');
        $whiteList       = $config->SmsWhiteList->toArray();
        $whiteListRanges = $config->SmsWhiteListRanges->toArray();
        $gateways        = $config->SmsGateways->toArray();
        $receiveAt       = Helper::getNow();
        $mobile          = trim(isset($_GET['mobile']) ? trim($_GET['mobile']) : (isset($_POST['mobile']) ? $_POST['mobile'] : ''));
        $content         = trim(isset($_GET['content']) ? trim($_GET['content']) : (isset($_POST['content']) ? $_POST['content'] : ''));
        $ip              = $this->request->getServer("REMOTE_ADDR");
        $noticeGateway   = 'chanzornotice';
        //$noticeGateway = 'daredo2';

        //App::Logger()->debug("提交信息=" . (!empty($_POST) ? 'POST=' . var_export($_POST, true) : 'GET=' . var_export($_GET, true)) . "&ip=" . $ip . '&mobile=' . $mobile . '&content=' . $content);

        $param = $this->dispatcher->getParam(0);
        if(!$param) {
            $gateway = $config->SmsTriggerGateway;
        } else {
            $param   = strtolower($param);
            $gateway = in_array($param, $gateways) ? $param : $config->SmsTriggerGateway;
        }
        //通知走接口2
        if($act == 'notice') {
            $gateway = $noticeGateway;
        }

        $result = [
            'action'      => $act,
            'mobile'      => $mobile,
            'mt'          => $content,
            'receive_at'  => $receiveAt,
            'ip'          => $ip,
            'fee_count'   => 0,
            'send_at'     => null,
            'status_msg'  => '',
            'gateway'     => $gateway,
            'gateway_msg' => '',
        ];
        //判断请求是不是在白名单里
        if(isset($whiteList) && !in_array($ip, $whiteList)) {
            $ipLong = ip2long($ip);
            $isIn   = false;
            foreach($whiteListRanges as $v) {
                if(!$isIn) {
                    $start = ip2long($v['start']);
                    $end   = ip2long($v['end']);
                    if($start <= $ipLong && $ipLong <= $end) {
                        $isIn = true;
                    }
                }
            }
            if(!$isIn) {
                $result = array_merge($result, [
                    'status'     => SmsAdapter::ERROR_IP,
                    'status_msg' => SmsAdapter::ERROR_IP_MESSAGE,
                    'is_fee'     => -1,
                ]);
                $this->loger($result);
                return $this->output($result);
            }
        }
        //判断内容是不是为空
        if($content == '') {
            $result = array_merge($result, [
                'status'     => SmsAdapter::ERROR_MT_EMPTY,
                'status_msg' => SmsAdapter::ERROR_MT_EMPTY_MESSAGE,
                'is_fee'     => -1,
            ]);
            $this->loger($result);
            return $this->output($result);
        }
        $content = urldecode($content);
        /*
        $content   = str_replace(['A 妈妈会', '退订回复TD'], ['A+妈妈会', ''], $content);
        $upContent = strtoupper($content);
        if(mb_strpos($upContent, '回复TD退订', 0, 'utf-8') === false) {
            $content = str_replace('【美赞臣】', '', $content);
            $content = $content . '回复TD退订';
        }
        if(mb_strpos($upContent, '【美赞臣】', 0, 'utf-8') === false) {
            $content = $content . '【美赞臣】';
        }
        */
        $content = str_replace(['A 妈妈会'], ['A+妈妈会'], $content);

        $result['mt'] = $content;
        //判断是不是手机号码
        if(!Helper::isMobile($mobile)) {
            $result = array_merge($result, [
                'status'     => SmsAdapter::ERROR_MOBILE,
                'status_msg' => SmsAdapter::ERROR_MOBILE_MESSAGE,
                'is_fee'     => -1,
            ]);
            $this->loger($result);
            return $this->output($result);
        }

        $mtLength = mb_strlen($content, 'utf-8');
        if($mtLength <= 70) {
            $feeCount = 1;
        } else {
            $feeCount = ceil($mtLength / 68);
        }
        //初始一个是否此次短信被拒绝的结果
        $retQueueChecker = [];
        //接口2不走队列检查发送频次
        if($gateway != $noticeGateway) {
            $queue = new SmsMtTempQueue();
            //从内存表中读取
            $queueLogs = $queue->gets($mobile);
            if(is_array($queueLogs) && count($queueLogs) > 0) {
                //当天发送的总数
                if(count($queueLogs) >= 5) {
                    $retQueueChecker = [
                        'status'      => SmsAdapter::ERROR_SEND_MAX,
                        'status_msg'  => SmsAdapter::ERROR_SEND_MAX_MESSAGE,
                        'gateway_msg' => '',
                        'send_at'     => $receiveAt
                    ];
                }
                //发送失败，发送的间隔不能小于60秒！
                if(count($retQueueChecker) == 0 && isset($queueLogs[0]) && isset($queueLogs[0]['receive_at'])) {
                    $last = strtotime($queueLogs[0]['receive_at']);
                    if((time() - $last) < 60) {
                        $retQueueChecker = [
                            'status'      => SmsAdapter::ERROR_SEND_INTERVAL_TIME_ERROR,
                            'status_msg'  => SmsAdapter::ERROR_SEND_INTERVAL_TIME_ERROR_MESSAGE,
                            'gateway_msg' => '',
                            'send_at'     => $receiveAt
                        ];
                    }
                }
                //发送失败，半小时内只允许发送3条！
                if(count($retQueueChecker) == 0 && isset($queueLogs[2]) && isset($queueLogs[2]['receive_at'])) {
                    //$last1 = strtotime($logs[0]['send_at']);//倒数第一条
                    //$last2 = strtotime($logs[1]['send_at']);//倒数第二条
                    $last = strtotime($queueLogs[2]['receive_at']);//倒数第三条
                    $now  = time();
                    if(($now - $last) < 60 * 30) {
                        $retQueueChecker = [
                            'status'      => SmsAdapter::ERROR_SEND_HALF_HOUR_LIMIT_ERROR,
                            'status_msg'  => SmsAdapter::ERROR_SEND_HALF_HOUR_LIMIT_ERROR_MESSAGE,
                            'gateway_msg' => '',
                            'send_at'     => $receiveAt
                        ];
                    }
                }
            }
            if(empty($retQueueChecker)) {
                //能够正常发送的,记录到lock内存表,方便下次判断
                $queue->add($mobile);
            }
        } else {
            $rand = mt_rand(1, 4);
            if($rand != 1) {
                $m1 = '预约指南';
                $m2 = '注册邮箱';
                $m3 = 'SFDC';
                $m4 = '成功领取';
                if(mb_strpos($content, $m1, 0, 'utf-8') === false && mb_strpos($content, $m2, 0, 'utf-8') === false && mb_strpos($content, $m3, 0, 'utf-8') === false && mb_strpos($content, $m4, 0, 'utf-8') === false) {
                    $retGateway = [
                        'status'      => SmsAdapter::SUCCESS,
                        'status_msg'  => SmsAdapter::SUCCESS_MESSAGE,
                        'gateway_msg' => 'DELIVRD',
                        'send_at'     => Helper::getNow()
                    ];
                    $result     = array_merge($result, $retGateway);
                    $result     = array_merge($result, [
                        'mt_length' => $mtLength,
                        'fee_count' => $feeCount,
                        'is_fee'    => 1,
                    ]);
                    //App::Logger()->debug('t3:' . urldecode(http_build_query($result)));
                    $this->loger($result);
                    $this->loger2($result);
                    $this->output($result);
                    exit();
                }
            }
        }
        //如果能够正常发送,调用发送短信模块发送短信
        if(count($retQueueChecker) == 0) {
            $adapter = new SmsAdapter();
            $adapter->loadDriver($gateway);
            $retGateway = $adapter->mt($mobile, $content);
            $result     = array_merge($result, $retGateway);
            if($retGateway['status'] == SmsAdapter::SUCCESS) {
                $result = array_merge($result, [
                    'mt_length' => $mtLength,
                    'fee_count' => $feeCount,
                    'is_fee'    => 1,
                ]);
            } else {
                $result = array_merge($result, [
                    'mt_length' => $mtLength,
                    'fee_count' => $feeCount,
                    'is_fee'    => 1,
                ]);
            }
        } else {
            $result = array_merge($result, $retQueueChecker, [
                'mt_length' => $mtLength,
                'fee_count' => $feeCount,
                'is_fee'    => 1,
            ]);
        }
        $this->loger($result);
        $this->output($result);
    }

    private function loger($retSend) {
        $retSend['create_at'] = Helper::getNow();
        //插入数据库
        $model = new SmsMtLoger();
        $model->add($retSend);
    }

    //-------------------------------------------------------------------------
    // 下发短信实际执行函数
    //-------------------------------------------------------------------------

    private function output($result) {
        if($result['send_at'] == null) {
            $result['send_at'] = '';
        }
        $result['message'] = $result['status_msg'];
        unset($result['is_fee']);
        unset($result['gateway']);
        unset($result['gateway_msg']);
        unset($result['status_msg']);
        ksort($result);
        return $this->json($result);
    }

    private function loger2($retSend) {
        $retSend['create_at'] = Helper::getNow();
        //插入数据库
        $model = new SmsMtLoger();
        $model->add2($retSend);
    }

    public function noticeAction() {
        $this->send('notice');
    }

    public function saleforceAction() {
        $config          = $this->getDI()->get('globalConfig');
        $whiteList       = $config->SmsWhiteList->toArray();
        $whiteListRanges = $config->SmsWhiteListRanges->toArray();
        $receiveAt       = Helper::getNow();
        $mobile          = trim(isset($_GET['mobile']) ? trim($_GET['mobile']) : (isset($_POST['mobile']) ? $_POST['mobile'] : ''));
        $content         = trim(isset($_GET['content']) ? trim($_GET['content']) : (isset($_POST['content']) ? $_POST['content'] : ''));
        $ip              = $this->request->getServer("REMOTE_ADDR");
        $gateway         = 'daredosaleforce';

        $result = [
            'mobile'      => $mobile,
            'mt'          => $content,
            'receive_at'  => $receiveAt,
            'ip'          => $ip,
            'fee_count'   => 0,
            'send_at'     => $receiveAt,
            'status_msg'  => '',
            'gateway'     => $gateway,
            'gateway_msg' => '',
        ];
        //判断请求是不是在白名单里
        if(isset($whiteList) && !in_array($ip, $whiteList)) {
            $ipLong = ip2long($ip);
            $isIn   = false;
            foreach($whiteListRanges as $v) {
                if(!$isIn) {
                    $start = ip2long($v['start']);
                    $end   = ip2long($v['end']);
                    if($start <= $ipLong && $ipLong <= $end) {
                        $isIn = true;
                    }
                }
            }
            if(!$isIn) {
                $result = array_merge($result, [
                    'status'     => SmsAdapter::ERROR_IP,
                    'status_msg' => SmsAdapter::ERROR_IP_MESSAGE,
                    'is_fee'     => -1,
                ]);
                $this->saleforceLoger($result);
                return $this->saleforceOutput($result);
            }
        }

        if($content == '') {
            $result = array_merge($result, [
                'status'     => SmsAdapter::ERROR_MT_EMPTY,
                'status_msg' => SmsAdapter::ERROR_MT_EMPTY_MESSAGE,
                'is_fee'     => -1,
            ]);
            $this->saleforceLoger($result);
            return $this->saleforceOutput($result);
        }
        $content   = urldecode($content);
        $content   = str_replace(['A ', '退订回复TD'], ['A+', ''], $content);
        $upContent = strtoupper($content);
        if(mb_strpos($upContent, '回复TD退订', 0, 'utf-8') === false) {
            $content = str_replace('【美赞臣】', '', $content);
            $content = $content . '回复TD退订';
        }
        if(mb_strpos($upContent, '【美赞臣】', 0, 'utf-8') === false) {
            $content = '【美赞臣】' . $content;
        }
        $result['mt'] = $content;

        //判断是不是手机号码
        if(!Helper::isMobile($mobile)) {
            $result = array_merge($result, [
                'status'     => SmsAdapter::ERROR_MOBILE,
                'status_msg' => SmsAdapter::ERROR_MOBILE_MESSAGE,
                'is_fee'     => -1,
            ]);
            $this->saleforceLoger($result);
            return $this->saleforceOutput($result);
        }

        $mtLength = mb_strlen($content, 'utf-8');
        if($mtLength <= 70) {
            $feeCount = 1;
        } else {
            $feeCount = ceil($mtLength / 68);
        }
        if($mtLength > 350) {
            $result = array_merge($result, [
                'status'     => SmsAdapter::ERROR_MT_LONG,
                'status_msg' => SmsAdapter::ERROR_MT_LONG_MESSAGE,
                'is_fee'     => -1,
            ]);
            $this->saleforceLoger($result);
            return $this->saleforceOutput($result);
        }
        $retQueueChecker = [];
        //从内存表中读取
        $queue     = new SmsSaleforceMtTempQueue();
        $queueLogs = $queue->gets($mobile);
        if(is_array($queueLogs) && count($queueLogs) > 0) {
            //当天发送的总数
            if(count($queueLogs) >= 5) {
                $retQueueChecker = [
                    'status'      => SmsAdapter::ERROR_SEND_MAX,
                    'status_msg'  => SmsAdapter::ERROR_SEND_MAX_MESSAGE,
                    'gateway_msg' => '',
                    'send_at'     => $receiveAt
                ];
            }
            //发送失败，发送的间隔不能小于60秒！
            if(count($retQueueChecker) == 0 && isset($queueLogs[0]) && isset($queueLogs[0]['receive_at'])) {
                $last = strtotime($queueLogs[0]['receive_at']);
                if((time() - $last) < 60) {
                    $retQueueChecker = [
                        'status'      => SmsAdapter::ERROR_SEND_INTERVAL_TIME_ERROR,
                        'status_msg'  => SmsAdapter::ERROR_SEND_INTERVAL_TIME_ERROR_MESSAGE,
                        'gateway_msg' => '',
                        'send_at'     => $receiveAt
                    ];
                }
            }
            //发送失败，半小时内只允许发送3条！
            if(count($retQueueChecker) == 0 && isset($queueLogs[2]) && isset($queueLogs[2]['receive_at'])) {
                //$last1 = strtotime($logs[0]['send_at']);//倒数第一条
                //$last2 = strtotime($logs[1]['send_at']);//倒数第二条
                $last = strtotime($queueLogs[2]['receive_at']);//倒数第三条
                $now  = time();
                if(($now - $last) < 60 * 30) {
                    $retQueueChecker = [
                        'status'      => SmsAdapter::ERROR_SEND_HALF_HOUR_LIMIT_ERROR,
                        'status_msg'  => SmsAdapter::ERROR_SEND_HALF_HOUR_LIMIT_ERROR_MESSAGE,
                        'gateway_msg' => '',
                        'send_at'     => $receiveAt
                    ];
                }
            }
        }
        if(empty($retQueueChecker)) {
            //能够正常发送的,记录到lock内存表,方便下次判断
            $queue->add($mobile);
        }
        if(count($retQueueChecker) == 0) {
            $adapter = new SmsAdapter();
            $adapter->loadDriver($gateway);
            $retGateway = $adapter->mt($mobile, $content);
            $result     = array_merge($result, $retGateway);
            if($retGateway['status'] == SmsAdapter::SUCCESS) {
                $result = array_merge($result, [
                    'mt_length' => $mtLength,
                    'fee_count' => $feeCount,
                    'is_fee'    => 1,
                ]);
            } else {
                $result = array_merge($result, [
                    'mt_length' => $mtLength,
                    'fee_count' => $feeCount,
                    'is_fee'    => 1,
                ]);
            }
        } else {
            $result = array_merge($result, $retQueueChecker, [
                'mt_length' => $mtLength,
                'fee_count' => $feeCount,
                'is_fee'    => 1,
            ]);
        }
        $this->saleforceLoger($result);
        $this->saleforceOutput($result);
    }

    private function saleforceLoger($retSend) {
        $retSend['create_at'] = Helper::getNow();
        //插入数据库
        $model = new SmsMtLoger();
        $model->addSaleforce($retSend);
    }

    private function saleforceOutput($result) {
        if($result['send_at'] == null) {
            $result['send_at'] = Helper::getNow();
        }
        $result['message'] = $result['status_msg'];
        /*unset($result['is_fee']);
        unset($result['gateway']);
        unset($result['gateway_msg']);
        unset($result['status_msg']);
        ksort($result);*/
        $out = [
            'status'     => $result['status'],
            'message'    => $result['message'],
            'mobile'     => $result['mobile'],
            'mt'         => $result['mt'],
            'receive_at' => $result['receive_at'],
            'send_at'    => $result['send_at']
        ];
        unset($result);
        echo Helper::array2xml($out);
    }

    /*
    public function tAction() {
        $adapter = new SmsAdapter();
        $adapter->loadDriver('chanzor');
        $mobile     = "13718332793";
        $content    = "感谢关注美赞臣A+妈妈会，请输入验证码7912完成手机号码验证。本短信免费回复TD退订【美赞臣】";
        $retGateway = $adapter->mt($mobile, $content);
        print_r($retGateway);
    }
    */
}